﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using Oscilloscope.Util;

namespace Oscilloscope.ChannelBuffer
{
    // Token: 0x02000017 RID: 23
    internal class FileChannelBuffer : IChannelBuffer, IDisposable
    {
        // Token: 0x060000FA RID: 250 RVA: 0x00008630 File Offset: 0x00006830

        public FileChannelBuffer(string filePath, string strType)
        {

            this.fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.None);
            this.sampleFrenquency = this.ReadUshort(this.fs);
            int num = this.ReadUshort(this.fs);
            int num2 = this.ReadUshort(this.fs);

            if (num2 == 1)
            {
                this.signalType = SignalType.AnalogSigned;
            }
            else if (num2 == 0)
            {
                this.signalType = SignalType.AnalogUnsigned;
            }
            if (num >= 0)
            {

                var typeStrings = strType.Split('$')[0];
                var offsetStrings = strType.Split('$')[2];
                var typeStringDecimalCount = strType.Split('$')[1].Split('*')[0];
                switch (int.Parse(strType.Split('$')[1].Split('*')[0]))
                {
                    case 1:
                        this.RatioType = SignalRatio.x1;
                        break;
                    case 10:
                        this.RatioType = SignalRatio.x10;
                        break;
                    case 100:
                        this.RatioType = SignalRatio.x100;
                        break;
                    case 1000:
                        this.RatioType = SignalRatio.x1k;
                        break;
                    case 10000:
                        this.RatioType = SignalRatio.x10k;
                        break;
                    case 100000:
                        this.RatioType = SignalRatio.x100k;
                        break;
                }
                if (typeStrings == "F32")
                {
                    this.DataType = DataType.浮点;
                    this.referenceValue = (double)((double)num / double.Parse(typeStringDecimalCount));
                    this.signalType = SignalType.AnalogSigned;
                    this.Offset = double.Parse(offsetStrings);
                    //Console.WriteLine($"当前倍率{typeStringDecimalCount}"+this.referenceValue);
                    //this.signalType = SignalType.AnalogSigned;

                }
                else if (typeStrings == "I16")
                {
                    this.DataType = DataType.整;
                    this.referenceValue = (double)((short)num);
                    this.signalType = SignalType.AnalogSigned;
                    this.Offset = double.Parse(offsetStrings);

                }
                else if (typeStrings == "U16")
                {
                    this.DataType = DataType.整;
                    this.referenceValue = (double)((ushort)num);
                    this.signalType = SignalType.AnalogUnsigned;
                    this.Offset = double.Parse(offsetStrings);

                }
                else if (typeStrings == "MultiBit")
                {
                    this.DataType = DataType.整;
                    this.referenceValue = (double)((ushort)num);
                    this.signalType = SignalType.DigitalMultiple;
                    this.Offset = double.Parse(offsetStrings);

                }
            }
        }




        public double GetTimeInterval()
        {
            if (this.fs == null || this.sampleFrenquency <= 0)
            {
                return 0.0;
            }
            return 1.0 / (double)this.sampleFrenquency;
        }

        public double GetTotalTime()
        {
            if (this.GetTimeInterval() <= 0.0)
            {
                return 0.0;
            }
            double num = (double)((this.fs.Length - (long)FileChannelBuffer.DATA_OFFSET) / 3L - 1L) * this.GetTimeInterval();
            if (num <= 0.0)
            {
                return 0.0;
            }
            return num;
        }

        // Token: 0x060000FD RID: 253 RVA: 0x00008760 File Offset: 0x00006960
        public double GetReferenceValue()
        {
            return this.referenceValue;
        }

        // Token: 0x060000FE RID: 254 RVA: 0x00008768 File Offset: 0x00006968
        public SignalType GetSignalType()
        {
            return this.signalType;
        }

        /// <summary>
        /// 获取buffer内部的数据
        /// </summary>
        /// <param name="startTime"></param>
        /// <param name="endTime"></param>
        /// <param name="buffer"></param>
        /// <param name="offset"></param>
        /// <param name="timeOfFirstData"></param>
        /// <returns></returns>
        /// <exception cref="IndexOutOfRangeException"></exception>
        public int GetData(double startTime, double endTime, ChannelBufferData[] buffer, int offset, ref double timeOfFirstData)
        {
            long num = 0L;
            int dataByteRange = this.GetDataByteRange(startTime, endTime, ref num);
            if (dataByteRange == 0)
            {
                return 0;
            }
            if (offset + dataByteRange > buffer.Length)
            {
                throw new IndexOutOfRangeException();
            }
            this.fs.Position = num;
            for (int i = 0; i < dataByteRange; i++)
            {
                //if (this.DataType== DataType.浮点)
                {
                    //修改buffer内的数据
                    double ushortData = 0;
                    switch (this.signalType) {
                    case SignalType.AnalogSigned:
                            ushortData = (double)((short)this.ReadUshort(this.fs));
                        break;  
                case SignalType.AnalogUnsigned:
                            ushortData = (double)((ushort)this.ReadUshort(this.fs));
                        break;  
                case SignalType.DigitalMultiple:
                        buffer[i + offset].Data = (ushortData * this.referenceValue);
                        break;  
                default:
                        break;
                    }
                    var signalRatio = this.RatioType;
                    var sRatio = 0;
                    switch (signalRatio)
                    {
                        case SignalRatio.x1:
                            sRatio = (int)SignalRatio.x1;
                            break;
                        case SignalRatio.x10:
                            sRatio = (int)SignalRatio.x10;
                            break;
                        case SignalRatio.x100:
                            sRatio = (int)SignalRatio.x100;
                            break;
                        case SignalRatio.x1k:
                            sRatio = (int)SignalRatio.x1k;
                            break;
                        case SignalRatio.x10k:
                            sRatio = (int)SignalRatio.x10k;
                            break;
                        case SignalRatio.x100k:
                            sRatio = (int)SignalRatio.x100k;
                            break;
                        default:
                            break;
                    }
                    buffer[i + offset].Data = (ushortData * ((double)1 / (double)sRatio)) + this.Offset;
                }
                //else
                //{
                //                if (this.signalType == SignalType.AnalogSigned)
                //                {
                //                    //修改buffer内的数据
                //                    buffer[i + offset].Data = (double)((short)this.ReadUshort(this.fs));
                //                }
                //                else
                //                {
                //                    buffer[i + offset].Data = (double)this.ReadUshort(this.fs);
                //                }
                //            }
                buffer[i + offset].IsValid = this.ReadValidFlag(this.fs);
            }
            timeOfFirstData = (double)((num - (long)FileChannelBuffer.DATA_OFFSET) / 3L) * this.GetTimeInterval();
            return dataByteRange;
        }

        // Token: 0x06000100 RID: 256 RVA: 0x0000882C File Offset: 0x00006A2C
        public int GetDataCount(double startTime, double endTime)
        {
            long num = 0L;
            return this.GetDataByteRange(startTime, endTime, ref num);
        }

        // Token: 0x06000101 RID: 257 RVA: 0x00008848 File Offset: 0x00006A48
        private int GetDataByteRange(double startTime, double endTime, ref long firstDataStartByteIndex)
        {
            if (startTime < 0.0 || endTime < 0.0 || endTime < startTime)
            {
                throw new ArgumentOutOfRangeException();
            }
            if (startTime == endTime || this.GetTotalTime() <= 0.0)
            {
                return 0;
            }
            double integralMultipleOfStepBaseValueOf = InternalUtils.GetIntegralMultipleOfStepBaseValueOf(startTime, this.GetTimeInterval(), false);
            double integralMultipleOfStepBaseValueOf2 = InternalUtils.GetIntegralMultipleOfStepBaseValueOf(endTime, this.GetTimeInterval(), true);
            if (integralMultipleOfStepBaseValueOf > this.GetTotalTime())
            {
                return 0;
            }
            long num = Convert.ToInt64(integralMultipleOfStepBaseValueOf / this.GetTimeInterval());
            long num2 = Convert.ToInt64(integralMultipleOfStepBaseValueOf2 / this.GetTimeInterval());
            long num3 = (long)FileChannelBuffer.DATA_OFFSET + num * 3L;
            long num4;
            for (num4 = num3; num4 >= (long)FileChannelBuffer.DATA_OFFSET; num4 -= 3L)
            {
                this.fs.Position = num4;
                this.ReadUshort(this.fs);
                if (this.ReadValidFlag(this.fs))
                {
                    break;
                }
            }
            if (num4 >= (long)FileChannelBuffer.DATA_OFFSET)
            {
                num3 = num4;
            }
            long num5 = (long)FileChannelBuffer.DATA_OFFSET + num2 * 3L;
            if (num5 > this.fs.Length - 3L)
            {
                num5 = this.fs.Length - 3L;
            }
            for (num4 = num5; num4 <= this.fs.Length - 3L; num4 += 3L)
            {
                this.fs.Position = num4;
                this.ReadUshort(this.fs);
                if (this.ReadValidFlag(this.fs))
                {
                    break;
                }
            }
            if (num4 <= this.fs.Length - 3L)
            {
                num5 = num4;
            }
            int result = (int)((num5 - num3) / 3L + 1L);
            firstDataStartByteIndex = num3;
            return result;
        }

        // Token: 0x06000102 RID: 258 RVA: 0x000089D3 File Offset: 0x00006BD3
        public void Dispose()
        {
            if (this.fs != null)
            {
                this.fs.Close();
                this.fs.Dispose();
                this.fs = null;
            }
        }

        // Token: 0x06000103 RID: 259 RVA: 0x000089FC File Offset: 0x00006BFC
        private int ReadUshort(FileStream fs)
        {
            if (fs == null)
            {
                throw new ArgumentNullException();
            }
            int num = 0;
            int num2 = fs.ReadByte();
            if (num2 < 0)
            {
                return -1;
            }
            num |= num2;
            num <<= 8;
            num2 = fs.ReadByte();
            if (num2 < 0)
            {
                return -1;
            }
            return num | num2;
        }

        // Token: 0x06000104 RID: 260 RVA: 0x00008A3C File Offset: 0x00006C3C
        private bool ReadValidFlag(FileStream fs)
        {
            if (fs == null)
            {
                throw new ArgumentNullException();
            }
            int num = fs.ReadByte();
            return num > 0;
        }

        // Token: 0x06000105 RID: 261 RVA: 0x00008A60 File Offset: 0x00006C60
        public void AddSampleData(short? data)
        {
        }

        // Token: 0x06000106 RID: 262 RVA: 0x00008A62 File Offset: 0x00006C62
        public IChannelBuffer Copy()
        {
            return this;
        }

        // Token: 0x06000107 RID: 263 RVA: 0x00008A65 File Offset: 0x00006C65
        public void CopyTo(IChannelBuffer desChannelBuffer)
        {
        }

        // Token: 0x04000068 RID: 104
        private static readonly int DATA_OFFSET = 6;

        // Token: 0x04000069 RID: 105
        private FileStream fs;

        // Token: 0x0400006A RID: 106
        private int sampleFrenquency = -1;

        // Token: 0x0400006B RID: 107
        private double referenceValue;

        // Token: 0x0400006C RID: 108
        private SignalType signalType;
        private SignalRatio RatioType;
        private double Offset;
        private DataType DataType;
    }
}
